﻿/*
 * KLF Headless Browser
 * Written by Kris Oye <kristianoye@gmail.com>
 * Copyright (C) 2011-2012.  All rights reserved.
 */
namespace KLF.Lib.Browser.DOM.HTML
{
    #region Using Statements

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using KLF.Lib.Browser.DOM.HTML;

    #endregion

    /// <summary>
    /// The DOMImplementation interface provides a number of methods for 
    /// performing operations that are independent of any particular 
    /// instance of the document object model. 
    /// </summary>
    public class HTMLImplementation : DOMImplementation
    {
        #region DOM Level 1 Compliance

        public override bool hasFeature(string feature, string version)
        {
            double dblVersion;

            if (feature.StartsWith("+"))
                feature = feature.Substring(1);

            if (Double.TryParse(version, out dblVersion))
            {
                switch (feature.ToLowerInvariant())
                {
                    case "html": case "xhtml":
                        return (dblVersion <= 2.0);
                }
            }
            return base.hasFeature(feature, version);
        }

        #endregion

        #region DOM Level 2 Compliance

        public override DocumentType createDocumentType(string qualifiedName, string publicId, string systemId)
        {
            return HtmlDocumentType.Create(qualifiedName, publicId, systemId);
        }

        public override Document createDocument(string qualifiedName, string publicId, string systemId)
        {
            return HtmlDocumentType.Create(qualifiedName, publicId, systemId).CreateDocument();
        }

        #endregion

        #region DOM Level 3 Compliance

        /// <summary>
        /// This method returns a specialized object which implements the 
        /// specialized APIs of the specified feature and version, as specified
        /// in DOM Features. The specialized object may also be obtained by
        /// using binding-specific casting methods but is not necessarily 
        /// expected to, as discussed in Mixed DOM Implementations. This method
        /// also allow the implementation to provide specialized objects which
        /// do not support the DOMImplementation interface. 
        /// </summary>
        /// 
        /// <param name="feature">The name of the feature requested. Note that
        /// any plus sign "+" prepended to the name of the feature will be 
        /// ignored since it is not significant in the context of this method.</param>
        /// 
        /// <param name="version">This is the version number of the feature to test.</param>
        /// 
        /// <returns>Returns an object which implements the specialized APIs 
        /// of the specified feature and version, if any, or null if there is
        /// no object which implements interfaces associated with that feature.
        /// If the DOMObject returned by this method implements the 
        /// DOMImplementation interface, it must delegate to the primary core 
        /// DOMImplementation and not return results inconsistent with the 
        /// primary core DOMImplementation such as hasFeature, getFeature, 
        /// etc. </returns>
        public override object getFeature(string feature, string version)
        {
            return new NotImplementedException();
        }

        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public class HtmlDocumentType : DocumentType
    {
        protected HtmlDocumentType()
            : base()
        {
        }

        internal HtmlDocumentType(Document owner, string _rawTypeDeclaration)
            : base(owner, _rawTypeDeclaration)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        internal override Document CreateDocument()
        {
            Document result = (Document)Activator.CreateInstance(DocType);

            result._DocumentType = this;

            return result;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="qualifiedName"></param>
        /// <param name="publicId"></param>
        /// <param name="systemId"></param>
        /// <returns></returns>
        internal static new DocumentType Create(string qualifiedName, string publicId, string systemId)
        {
            HtmlDocumentType returnValue = new HtmlDocumentType()
            {
                name = qualifiedName,
                publicId = publicId,
                systemId = systemId
            };

            if (!String.IsNullOrEmpty(systemId) &&
                systemId.ToLowerInvariant().Contains("xhtml"))
            {
                returnValue.DocType = typeof(XHTMLDocument);
            }
            else
            {
                returnValue.DocType = typeof(HTMLDocument);
            }

            return returnValue;
        }
    }
}
